
#include "WSListener.h"

WSListener::WSListener(ConnectHookPtr _hookptr) : hookPtr(_hookptr)
{}

void WSListener::onPing(const WebSocket& socket, const oatpp::String& message) {
  socket.sendPong(message);
}

void WSListener::onPong(const WebSocket& socket, const oatpp::String& message) {
}

void WSListener::onClose(const WebSocket& socket, v_uint16 code, const oatpp::String& message) {
}

void WSListener::readMessage(const WebSocket& socket, v_uint8 opcode, p_char8 data, oatpp::v_io_size size) {

static long allSize=0;
  if(size == 0) { // message transfer finished
    if(allSize==0) return;
    char* wholeMessage = (char*)m_messageBuffer.getData();
    m_messageBuffer.setCurrentPosition(0);
    int32_t FrameType;
    std::memcpy((char*)&FrameType,wholeMessage,sizeof(int32_t));
    wholeMessage+=sizeof(int32_t);
    switch (FrameType)
    {
    case 0x1:
      {
        int32_t imageHeight,imageWidth;
        pixelFormat imageFormat;
        std::memcpy((char*)&imageWidth,wholeMessage,sizeof(int32_t));
        wholeMessage+=sizeof(int32_t);
        std::memcpy((char*)&imageHeight,wholeMessage,sizeof(int32_t));
        wholeMessage+=sizeof(int32_t);
        std::memcpy((char*)&imageFormat,wholeMessage,sizeof(int32_t));
        wholeMessage+=sizeof(int32_t);
        unsigned char* imgPtr=new unsigned char[imageHeight*imageWidth];
        std::memcpy(imgPtr,wholeMessage,imageHeight*imageWidth);
        hookPtr->second.GetNewImage(imgPtr,imageWidth,imageHeight,imageFormat);
      }
      break;
    case 0x2:
      {
        std::string message;
        message.append(wholeMessage,allSize-sizeof(int32_t));
        hookPtr->second.ReceiveMessage(message);
      }
      break;
    case 0x4:
      {
        std::string deviceName;
        deviceName.append(wholeMessage,allSize-sizeof(int32_t));
        hookPtr->second.SetDeviceName(deviceName);
      }
      break;
    case 0x6:
      {
        int32_t value;
        std::memcpy((char*)&value,wholeMessage,sizeof(int32_t));
        hookPtr->second.GetNewReturn(value);
        hookPtr->second.SetGetDataReady(true);
      }
      break;
    case 0x7:
      if(allSize==sizeof(CameraParament)+sizeof(int32_t))
        hookPtr->second.GetCameraParaReturn(wholeMessage);
      break;
    case 0x9:
        hookPtr->second.HandleFileTransfer(wholeMessage,allSize-sizeof(int32_t));
      break;
    default:
      break;
    }
    allSize=0;
  } else if(size > 0) { // message frame received
    m_messageBuffer.writeSimple(data, size);
    allSize+=size;
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// WSInstanceListener

std::atomic<v_int32> WSInstanceListener::SOCKETS(0);

WSInstanceListener::WSInstanceListener(ServerHandle* _serverHandle) : serverHandle(_serverHandle)
{}

void WSInstanceListener::onAfterCreate(const oatpp::websocket::WebSocket& socket, const std::shared_ptr<const ParameterMap>& params) {
  SOCKETS ++;
  OATPP_LOGD(TAG, "New Incoming Connection. Connection count=%d", SOCKETS.load());
  socket.setListener(std::make_shared<WSListener>(serverHandle->CreateNewHook(&socket)));
}

void WSInstanceListener::onBeforeDestroy(const oatpp::websocket::WebSocket& socket) {
  SOCKETS --;
  serverHandle->RecyclingConnect(&socket);
  OATPP_LOGD(TAG, "Connection closed. Connection count=%d", SOCKETS.load());
}
